@file:Suppress("FunctionName")

package com.zxy.supplier_system.server.repository

import com.zxy.supplier_system.server.entity.CheckInventoryRecord
import com.zxy.supplier_system.server.entity.Employee
import com.zxy.supplier_system.server.entity.SystemService
import com.zxy.supplier_system.server.utils.SpecificationUtils
import com.zxy.supplier_system.server.utils.joinOnce
import org.springframework.data.jpa.domain.Specification
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
import org.springframework.data.jpa.repository.Query
import java.time.LocalDate
import java.time.OffsetDateTime

interface CheckInventoryRecordRepository : JpaRepository<CheckInventoryRecord, Int>, JpaSpecificationExecutor<CheckInventoryRecord> {

    fun findByIdAndCreatedBy_SystemService(id: Int, market_systemService: SystemService): CheckInventoryRecord?

    @Query("select createdDateTime from CheckInventoryRecord order by createdDateTime asc")
    fun findMinCreatedDateTime():OffsetDateTime?

    @Query("select createdDateTime from CheckInventoryRecord order by createdDateTime desc ")
    fun findMaxCreatedDateTime():OffsetDateTime?

    object Specifications {

        fun marketSaleManagerEqual(employeeId: Int): Specification<CheckInventoryRecord> {
            return Specification { root, _, criteriaBuilder ->
                MarketRepository.Specifications.saleManagerEqual(root.joinOnce("market"), criteriaBuilder, employeeId)
            }
        }

        fun marketShoppingGuidesContains(employeeId: Int): Specification<CheckInventoryRecord> {
            return Specification { root, query, criteriaBuilder ->
                MarketRepository.Specifications.shoppingGuidesContains(
                    root.joinOnce("market"),
                    criteriaBuilder,
                    query,
                    employeeId
                )
            }
        }

        fun startDateGreaterThanOrEqualTo(startDate: LocalDate?): Specification<CheckInventoryRecord> {
            return Specification { root, _, criteriaBuilder ->
                startDate?.let {
                    criteriaBuilder.greaterThanOrEqualTo(root.get("createdDateTime"), it)
                }
            }
        }

        fun endDateLessThanOrEqualTo(endDate: LocalDate?): Specification<CheckInventoryRecord> {
            return Specification { root, _, criteriaBuilder ->
                endDate?.let {
                    criteriaBuilder.lessThanOrEqualTo(root.get("createdDateTime"), it)
                }
            }
        }

        fun employeeIn(employeeIds: List<Int>): Specification<CheckInventoryRecord> {
            return SpecificationUtils.`in`({ root ->
                root.joinOnce<CheckInventoryRecord, Employee>("createdBy").get("id")
            }, employeeIds)
        }

        fun submittedEquals(submitted:Boolean?):Specification<CheckInventoryRecord>{
            return SpecificationUtils.nullStatusByBoolean({root -> root.get("submittedDateTime") },submitted)
        }

    }


}

